﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;

namespace SharePointClient
{

    public class Document: IDisposable
    {
        public enum CheckInType
        { MinorCheckIn=0, MajorCheckIn=1, OverwriteCheckIn=2 }

        private XmlNode data;
        private List list;

        internal Document(List list, XmlNode node)
        {
            this.list = list;
            this.data = node;
        }
        internal void Update(List list, XmlNode node)
        {
            this.list = list;
            this.data = node;
        }
        public object Attribute(string name)
        {
            Field f=list.Fields[name];
            if (f != null) return f.ConvertToType(data.Attributes["ows_" + f.Name].Value);
            else return "";
        }
        private string GetApplication(string extension)
        {
            string ext = (string)Microsoft.Win32.Registry.GetValue("HKEY_CLASSES_ROOT\\." + extension.ToLower(), "", "");
            if (ext == null || ext == "") return GetApplication("txt");
            string defaulticon = (string)Microsoft.Win32.Registry.GetValue("HKEY_CLASSES_ROOT\\" + ext + "\\DefaultIcon", "", "");
            if (defaulticon == null || defaulticon == "")
            {
                string curver = (string)Microsoft.Win32.Registry.GetValue("HKEY_CLASSES_ROOT\\" + ext + "\\CurVer", "", "");
                if (curver == null || curver == "") return GetApplication("txt");
                defaulticon = (string)Microsoft.Win32.Registry.GetValue("HKEY_CLASSES_ROOT\\" + curver + "\\DefaultIcon", "", "");
            }
            if (defaulticon == null || defaulticon == "") return GetApplication("txt");
            return defaulticon.Split(new char[] { ',' })[0];
        }
        public string GetApplication()
        {
            return GetApplication(Extension);
        }
        public System.Drawing.Icon GetIcon()
        {
            try
            {
                return System.Drawing.Icon.ExtractAssociatedIcon(GetApplication());
            }
            catch (Exception e)
            {
                return System.Drawing.Icon.ExtractAssociatedIcon(Environment.GetEnvironmentVariable("SystemRoot")+"\\notepad.exe");
            }
         
        }
        public string Url 
        {
            get 
            {
                string url=(string) Attribute("FileRef");
               
                return Uri.EscapeUriString(list.Uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)+"/"+ url);
            }
        }
        public int ID { get { return (int)Attribute("ID"); } }
        public string Filename { get { return (string)Attribute("FileLeafRef"); } }
        public DateTime Created { get { return (DateTime)Attribute("Created"); } }
        public DateTime Modified { get { return (DateTime)Attribute("Modified"); } }
        public string CreatedBy { get { return (string)Attribute("Author"); } }
        public string ModifiedBy { get { return (string)Attribute("Editor"); } }
        public string Extension { get { string fn = Filename; return fn.Substring(fn.LastIndexOf('.')+1); } }
        public override string ToString()
        {
            return ID.ToString() + ":" + Filename;
        }
        public bool Download(string toFilename)
        {
            return list.Connection.Download(new Uri(Url), toFilename);
        }
        public bool Upload(string fromFilename)
        {
            return list.Connection.Upload(fromFilename, new Uri(Url));
        }
        #region IDisposable Member

        public void Dispose()
        {
            list = null;
            data = null;
        }

        #endregion

        public bool CheckIn(string comment, CheckInType checkInType)
        {
            return list.lists.CheckInFile(this.Url, comment, ((int)checkInType).ToString());
        }
        public bool CheckOut(bool toOfflineEditing)
        {
            if (toOfflineEditing)
                return list.lists.CheckOutFile(this.Url, "false", "");
            else
                return list.lists.CheckOutFile(this.Url, "true", "");
        }
        public string CheckoutUser { get { return Attribute["CheckoutUser"]; } }
        public bool CheckedOut { get { return CheckoutUser == ""; } }
        /*
        
        private Copy FileCopy
        {
            get
            {
                SPWebService.Copy.Copy copyService = new SPWebService.Copy.Copy();
                copyService.Url = Uri.ToString() + "_vti_bin/Copy.asmx";
                copyService.Credentials = Credentials;
                return copyService;
            }
        }
        public virtual object Upload(string filename,string destpath,List<Field> fields)
        {
            FieldInformation [] finfo;
            FileStream file;
            CopyResult[] result;
            byte[] filedata;
           
            if (fields == null) finfo = new FieldInformation[] {  };
            else
            {
                finfo = new FieldInformation[fields.Count];
                for (int i = 0; i < fields.Count; i++) finfo[i] = fields[i].FieldInformation;
            }


            file = new FileStream(filename, FileMode.Open);
            filedata = new byte[file.Length];
            file.Read(filedata, 0, Convert.ToInt32(file.Length));
            file.Close();
            file.Dispose();

            
            System.Diagnostics.Debug.WriteLine("Uploading \"" + filename+"\" to \""+Uri.ToString() + destpath + "\"");
            uint res = FileCopy.CopyIntoItems(new Uri(filename).ToString(), new string[] { Uri.EscapeUriString(Uri.ToString() + destpath) }, finfo, filedata, out result);
            
            return result;
        }
        public virtual object Download(string path, string filename, out List<Field> fields)
        {
            FileStream file ;
            FieldInformation[] finfo;
            uint result;
            byte[] filedata;
            fields = new List<Field>();
            System.Diagnostics.Debug.WriteLine("Downloading \"" + Uri.ToString() + path + "\" to \"" + filename + "\"");
            result = FileCopy.GetItem(Uri.ToString() + path, out finfo, out filedata);
            if (finfo == null) return result;
            foreach (FieldInformation f in finfo)
            {
                Field field=new Field(f.Id,f.InternalName,f.Type.ToString(),f.Value);
                fields.Add(field);
            }
            file = new FileStream(filename, FileMode.Create);
            file.Write(filedata, 0, filedata.Length);
            file.Close();
            file.Dispose();

            return result;
        }
         */
    }
}
